#ifndef MyVector_H
#define MyVector_H

template<typename Object>
class MyVector{
private:
	int theSize;
	int theCapacity;
	Object *objects;
public:
	typedef Object *iterator;
	typedef const Object *const_iterator;
	enum {SPARE_CAPACITY = 16};
	explicit MyVector( int init = 0 ): theSize(init),theCapacity(init + SPARE_CAPACITY){
		objects = new Object[theCapacity];
	}
	const MyVector&operator=(const MyVector&rhs){
		if(this != &rhs){
			delete []objects;
			theSize = rhs.theSize;
			theCapacity = rhs.theCapacity;
			objects = new Object[theCapacity];
			for(int i = 0; i < size; i++)
				objects[i] = rhs.objects[i];
		}
		return *this;
	}
	MyVector(const MyVector&rhs) : objects(NULL){
		operator=(rhs);
	}
	~MyVector(){
		delete []objects;
	}
	
	void resize(int newSize){
		if(newSize > theCapacity)
			reserve(newSize * 2 + 1);
		theSize = newSize;
	}
	void reserve(int newCapacity){
		if(newCapacity < theSize){
			return;
		}
		Object *newBase = new Object[newCapacity];
		for(int i = 0; i < theSize; i++)
			newBase[i] = objects[i];
		theCapacity = newCapacity;
		delete []objects;
		objects = NULL;
		objects = newBase;
	}
	Object& operator[](int index){
		return objects[index];
	}
	const Object& operator[](int index)const{
		return objects[index];
	}
	bool empty()const{
		return theSize? false:true;
	}
	int size()const{
		return theSize;
	}
	int capacity()const{
		return theCapacity;
	}
	void push_back(const Object& obj){
		if(theSize == theCapacity)
			reserve(theSize * 2 + 1);
		objects[theSize++] = obj;
	}
	void pop_back(){
		theSize--;
	}
	const Object& back()const{
		objects[theSize - 1];
	}
	iterator begin(){
		return &objects[0];
	}
	const_iterator begin()const{
		return objects;
	}
	iterator end(){
		return &objects[theSize];
	}
	const_iterator end()const{
		return objects + sizeof(Object) * theSize;
	}
	friend ostream& operator<<(ostream &os, const MyVector& vec){
		for(int i = 0; i < vec.size(); i++)
			os<<vec[i]<<" ";
		return os;
	}
};

#endif